package com.etxxy.remoting.service;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.VelocityException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.etxxy.common.security.BlowfishPropertiesFactory;
import com.etxxy.remoting.dto.MailRequestDTO;

@Service("mailSenderService")
public class MailSenderServiceImpl implements MailSenderService {

	private static final Logger logger = LoggerFactory.getLogger(MailSenderServiceImpl.class);
	@Autowired
	private JavaMailSenderImpl javaMailSenderImpl;
	@Autowired
	private VelocityEngine velocityEngine; // 模板解析
	@Value("${mail.username}")
	private String emailUserName;
	@Value("${mail.password}")
	private String emailPassword;
	@Value("${mail.production}")
	private String production;
	@Value("${mail.host}")
	private String host;
	@Value("${mail.nickname}")
	private String nickName;
	@Value("${mail.smtp.port}")
	private String port;

	private void sendMail(MimeMessage msg, MailRequestDTO mailBean) {
		Boolean isProduction = false;
		if (StringUtils.isNotBlank(production) && "true".equals(production)) {
			isProduction = Boolean.valueOf(production);
		}
		String password = "";

		if (isProduction) {
			password = emailPassword;
			try {
				password = BlowfishPropertiesFactory.decode(password);
			} catch (Exception e) {
				logger.error("解密错误e={}", e);
			}
		} else {
			password = emailPassword;
		}

		javaMailSenderImpl.setPassword(password);
		javaMailSenderImpl.setUsername(emailUserName);
		javaMailSenderImpl.setHost(host);
		javaMailSenderImpl.setPort(Integer.valueOf(port));
		javaMailSenderImpl.send(msg);
		logger.info(
				"$$$ Send mail Subject:" + mailBean.getSubject() + ", TO:" + JSON.toJSONString(mailBean.getToEmails()));

	}

	/*
	 * 根据 mailBean 创建 MimeMessage
	 */
	private MimeMessage createMimeMessage(MailRequestDTO mailBean) throws MessagingException {
		if (!checkMailBean(mailBean)) {
			return null;
		}
		String from = null;
		from = emailUserName;
		String text = getMessage(mailBean);
		if (text == null) {
			logger.warn("@@@ warn mail text is null (Thread name=" + Thread.currentThread().getName() + ") @@@ "
					+ mailBean.getSubject());
			return null;
		}
		MimeMessage msg = javaMailSenderImpl.createMimeMessage();
		MimeMessageHelper messageHelper = new MimeMessageHelper(msg, true, "UTF-8");
		try {
			messageHelper.setFrom(from, nickName);
		} catch (UnsupportedEncodingException e) {
			logger.error("操作失败", e);

		}
		messageHelper.setSubject(mailBean.getSubject());
		messageHelper.setTo(mailBean.getToEmails());
		messageHelper.setText(text, true); // html: true  
		return msg;
	}

	/*
	 * 模板解析
	 * 
	 * @param mailBean
	 * 
	 * @return
	 */
	private String getMessage(MailRequestDTO mailBean) {
		StringWriter writer = null;
		try {

			writer = new StringWriter();
			VelocityContext context = new VelocityContext(mailBean.getData());

			velocityEngine.evaluate(context, writer, "", mailBean.getTemplate());

			return writer.toString();
		} catch (VelocityException e) {
			logger.error(" VelocityException : " + mailBean.getSubject() + "\n" + e);
		} catch (IOException e) {
			logger.error(" IOException : " + mailBean.getSubject() + "\n" + e);
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					logger.error("###StringWriter close error ... ");
				}
			}
		}
		return null;
	}

	/*
	 * check 邮件
	 */
	private boolean checkMailBean(MailRequestDTO mailBean) {
		if (mailBean == null) {
			logger.warn("@@@ warn mailBean is null (Thread name=" + Thread.currentThread().getName() + ") ");
			return false;
		}
		if (mailBean.getSubject() == null) {
			logger.warn(
					"@@@ warn mailBean.getSubject() is null (Thread name=" + Thread.currentThread().getName() + ") ");
			return false;
		}
		if (mailBean.getToEmails() == null) {
			logger.warn(
					"@@@ warn mailBean.getToEmails() is null (Thread name=" + Thread.currentThread().getName() + ") ");
			return false;
		}
		if (mailBean.getTemplate() == null) {
			logger.warn(
					"@@@ warn mailBean.getTemplate() is null (Thread name=" + Thread.currentThread().getName() + ") ");
			return false;
		}
		return true;
	}

	/* ===================== setter & getter ======================= */
	public void setJavaMailSenderImpl(JavaMailSenderImpl javaMailSenderImpl) {
		this.javaMailSenderImpl = javaMailSenderImpl;
	}

	public void setVelocityEngine(VelocityEngine velocityEngine) {
		this.velocityEngine = velocityEngine;
	}

	@Override
	public boolean sendMail(MailRequestDTO mailBean) throws MessagingException {

		MimeMessage msg = createMimeMessage(mailBean);
		if (msg == null) {
			return false;
		}

		this.sendMail(msg, mailBean);

		return true;
	}

}
